﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PInitiatives.Models;
using System.Web.Security;

namespace PInitiatives.Areas.Administration.Controllers
{
    [AccessDeniedAuthorize(Roles = "Administrator")]
    public class AdminUserController : Controller
    {

        PInitiativesEntities db = new PInitiativesEntities();
        //
        // GET: /Administration/AdminUser/

        public ActionResult Index()
        {
            var users = db.Users.Include(u => u.aspnet_Users);
            ViewBag.CurrentUserName = HttpContext.User.Identity.Name;
            return View(users.ToList());
        }

        // GET
        public ActionResult Create()
        {
            ViewBag.Role = new SelectList(System.Web.Security.Roles.GetAllRoles());
            return View();
        }

        //POST

        [HttpPost]
        public ActionResult Create(ManageUserModel model)
        {
            if (ModelState.IsValid)
            {
                MembershipCreateStatus createStatus;
                System.Web.Security.MembershipUser newAspUser = Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, model.Active, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    System.Web.Security.Roles.AddUserToRole(newAspUser.UserName, model.Role);
                    
                    User user = new User(model.FirstName, model.SecondName, model.LastName, (Guid)newAspUser.ProviderUserKey);
                    db.Users.Add(user);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }
                
            }
            ViewBag.Role = new SelectList(System.Web.Security.Roles.GetAllRoles());
            return View(model);
        }


        //GET Edit
        public ActionResult Edit(int id)
        {
            User user = db.Users.Find(id);
            MembershipUser aspUser = Membership.GetUser(user.aspnet_Users.UserId);
            var role = Roles.GetRolesForUser(user.aspnet_Users.UserName).FirstOrDefault();
            ManageUserModel model = new ManageUserModel(user.ID, user.FirstName, user.SecondName, user.LastName, user.PostOnFB, user.Email, aspUser.UserName, role, aspUser.IsApproved);
            if (aspUser.UserName == HttpContext.User.Identity.Name)
                ViewBag.Role = null;
            else
                ViewBag.Role = new SelectList(System.Web.Security.Roles.GetAllRoles(), role);
            return View(model);
        }

        //POST Edit

        [HttpPost]
        public ActionResult Edit(ManageUserModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    User user = db.Users.Find(model.ID);
                    MembershipUser aspUser = Membership.GetUser(user.aspnet_Users.UserId);
                    if (!string.IsNullOrEmpty(model.Password))
                    {
                        aspUser.ChangePassword(aspUser.ResetPassword(), model.Password);
                    }
                    aspUser.Email = model.Email;
                    aspUser.IsApproved = model.Active;
                    Membership.UpdateUser(aspUser);
                    
                    var userRole = Roles.GetRolesForUser(aspUser.UserName).FirstOrDefault();
                    if (userRole != model.Role)
                    {
                        Roles.RemoveUserFromRole(aspUser.UserName, userRole);
                        Roles.AddUserToRole(aspUser.UserName, model.Role);
                    }
                    
                    //user.aspnet_Users.UserName = model.UserName;
                    user.FirstName = model.FirstName;
                    user.SecondName = model.SecondName;
                    user.LastName = model.LastName;
                    db.SaveChanges();

                    return RedirectToAction("Index");
                }
                catch
                {
                    ModelState.AddModelError("", "Błąd podczas zapisu, zmiany nie zostały zachowane !");
                }
            }

            var role = Roles.GetRolesForUser(db.Users.Find(model.ID).aspnet_Users.UserName).FirstOrDefault();
            ViewBag.Role = new SelectList(System.Web.Security.Roles.GetAllRoles(), role);
            return View(model);
        }

        public ActionResult Delete(int id)
        {
            var user = db.Users.Find(id);
            return View(user);
        }

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            var user = db.Users.Find(id);
            string userName = user.aspnet_Users.UserName;
            db.Users.Remove(user);
            db.SaveChanges();
            Membership.DeleteUser(userName, true);
            return RedirectToAction("Index");
        }

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion

    }
}
